<template>
  <el-card
    v-for="(item, index) in fileList"
    :key="index"
    :class="[deleteIndex === index ? 'fade_out_up_big' : 'rotate-z-in']"
    class="card-List animate__animated"
    shadow="hover"
  >
    <template v-if="item.loading">
      <div class="loading-box">
        <el-progress :percentage="item.percentage" class="progress" type="circle" />
      </div>
    </template>
    <template v-else>
      <div class="img-box">
        <div :style="{ height: isLookFileInfo ? '70%' : '100%' }" class="avatar">
          <el-image
            v-if="isMatchType(item.name, 'image')"
            :src="item.path"
            alt=""
            class="img-item"
            fit="cover"
          >
            <template #error>
              <div class="image-slot">
                <el-icon>
                  <Picture />
                </el-icon>
              </div>
            </template>
          </el-image>
          <div v-else :class="`icon-${checkFileType(item.name)}`" class="file-rests" />
          <div class="file-dusty">
            <el-icon class="font-icon" title="预览" @click="previewFile(item.name, item.path)">
              <ZoomIn />
            </el-icon>
            <el-icon class="font-icon" title="下载" @click="downloadFile(item)">
              <Download />
            </el-icon>
            <el-icon
              v-if="fileUploadType !== '1'"
              class="font-icon"
              title="删除"
              @click="deleteFile(index, item)"
            >
              <Delete />
            </el-icon>
          </div>
        </div>
        <div v-if="isLookFileInfo" class="imgInfo">
          <div :title="uploadFile(item.name)" class="imgInfoName">{{ uploadFile(item.name) }}</div>
          <div class="imgInfoSize">{{ fileSizeMb(item.size) }}</div>
        </div>
      </div>
    </template>
  </el-card>
  <!--  不能放到循环之中会造成打开重复预览文件组件-->
  <el-image-viewer
    v-if="showImageView"
    :initial-index="initialIndex"
    :url-list="srcPreviewList"
    hide-on-click-modal
    teleported
    @close="closeImagePreview"
  />
</template>

<script setup>
  import { computed, defineEmits, defineExpose, defineProps, onBeforeUnmount, ref } from 'vue'
  import useFile from '../useFile/index.js'
  import { Picture, ZoomIn, Download, Delete } from '@element-plus/icons-vue'
  import { ElMessage } from 'element-plus'

  const initialIndex = ref(0)
  const { checkFileType, uploadFile, fileSizeMb } = useFile()
  const props = defineProps({
    // 文件list
    fileList: {
      type: Array,
      default: () => []
    },
    // 是否查看文件信息
    isLookFileInfo: {
      type: Boolean,
      default: true
    },
    // 是否为详情页面,如果是详情页面的话就不需要展示删除文件的按钮
    fileUploadType: {
      type: String,
      default: '0',
      // 这里把类型控制起来
      validator(value) {
        return ['0', '1'].includes(value)
      }
    }
  })
  const emits = defineEmits(['deleteFile'])
  // 文件预览数组
  const srcPreviewList = computed(() =>
    props.fileList.filter((item) => isMatchType(item.name, 'image')).map((i) => i.path)
  )
  // 校验类型
  const isMatchType = (name, type) => {
    return checkFileType(name) === type
  }
  // 预览图片
  const showImageView = ref(false)

  // 预览文件
  const previewFile = (name, path) => {
    if (isMatchType(name, 'image')) {
      previewImage(path)
    } else if (isMatchType(name, 'pdf')) {
      previewPDF(path)
    } else {
      window.open(`https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(path)}`)
    }
  }

  // 图片预览
  const previewImage = (path) => {
    initialIndex.value = srcPreviewList.value.findIndex((item) => item === path)
    showImageView.value = true
  }

  // ptf预览
  const previewPDF = (path) => {
    window.open(path)
  }

  // 关闭图片预览功能
  const closeImagePreview = () => {
    showImageView.value = false
  }

  // 下载文件
  const downloadFile = (params) => {
    window.open(params.path)
  }
  // 删除文件
  const deleteIndex = ref(-1)
  const timerId = ref(null)
  const delFileList = ref([]) // 删除文件数组
  const deleteFile = (index, params) => {
    deleteIndex.value = index
    delFileList.value.push(params)
    // 这里添加异步是为了让动画有效进行
    timerId.value = setTimeout(() => {
      emits('deleteFile', params)
      ElMessage.success('删除成功')
      deleteIndex.value = -1
    }, 300)
  }
  // 卸载事件
  onBeforeUnmount(() => {
    // 清除定时器
    timerId.value && window.clearTimeout(timerId.value)
    timerId.value = null
  })
  defineExpose({ delFileList })
</script>

<style lang="scss" scoped>
  .card-List {
    padding: 10px;
    width: 180px;
    height: 180px;
    min-width: 110px;
    box-sizing: border-box;
    flex: 0 0 auto;

    &.animate__animated {
      -webkit-animation-duration: 1s;
      animation-duration: 1s;
      -webkit-animation-fill-mode: both;
      animation-fill-mode: both;
    }

    &.rotate-z-in {
      -webkit-animation-name: ROTATE-Z-IN;
      animation-name: ROTATE-Z-IN;
    }

    &.fade_out_up_big {
      -webkit-animation-name: FADEOUT_UP_BIG;
      animation-name: FADEOUT_UP_BIG;
    }

    :deep(.el-card__body) {
      padding: 0;
      height: 100%;

      .loading-box {
        height: 100%;
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;

        .progress {
          width: 100%;
          .el-progress-circle {
            width: 100% !important;
            height: 100% !important;
          }
        }
      }

      .img-box {
        display: flex;
        flex-direction: column;
        height: 100%;

        .avatar {
          height: 100%;
          position: relative;

          .img-item {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }

          .file-dusty {
            position: absolute;
            border-radius: 5px;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
            cursor: default;
            display: inline-flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            opacity: 0;
            font-size: 20px;
            background: rgba(0, 0, 0, 0.5);
            transition: opacity var(--el-transition-duration);

            .font-icon {
              cursor: pointer;

              &:hover {
                color: #38b2ea;
              }

              + .font-icon {
                margin-left: 10px;
              }
            }

            &:hover {
              opacity: 1;
            }
          }

          .file-rests {
            width: 100%;
            height: 100%;
            $iconList: ('pdf', 'word', 'excel', 'ppt', 'txt', 'zip');
            @each $value in $iconList {
              &.icon-#{$value} {
                background: url(('./image/#{$value}.svg')) no-repeat;
                background-size: 100% 100%;
              }
            }
          }
        }

        .imgInfo {
          font-size: 14px;
          height: 30%;

          .imgInfoSize {
            text-align: center;
          }

          .imgInfoName {
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            word-break: break-all;
            line-height: 1.2;
          }
        }
      }
    }
  }
  // 呼吸
  @keyframes BREATH {
    0% {
      transform: scale(0.8);
    }
    50% {
      transform: scale(1.2);
    }
    100% {
      transform: scale(0.8);
    }
  }

  // 水滴
  @keyframes DROP {
    0% {
      opacity: 0;
      transform: scale(0.1);
    }
    100% {
      opacity: 1;
      transform: scale(1.1);
    }
  }

  // 渐进
  @keyframes FADE-IN {
    0% {
      visibility: hidden;
    }
    1% {
      visibility: visible;
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }

  // 旋转进
  @keyframes ROTATE-Z-IN {
    0% {
      visibility: hidden;
    }
    1% {
      visibility: visible;
      transform: rotateZ(-20deg) scale(0.8);
      opacity: 0;
    }
    100% {
      opacity: 1;
      transform: rotateZ(0deg) scale(1);
    }
  }

  //移出动画
  @keyframes FADEOUT_UP_BIG {
    0% {
      opacity: 1;
    }
    100% {
      opacity: 0;
      -webkit-transform: translate3d(0, -2000px, 0);
      transform: translate3d(0, -2000px, 0);
    }
  }
</style>
